package com.delu.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.api.R;
import com.delu.data.Result;
import com.delu.em.ResultEnum;
import com.delu.entity.Advertisement;
import com.delu.entity.Field;
import com.delu.lock.AdvPayLock;
import com.delu.mapper.AdvMapper;
import com.delu.mapper.FieldMapper;
import com.delu.utils.IdWorker;
import com.delu.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("adv")
public class AdvController {

    @Autowired
    private AdvMapper advMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private AdvPayLock advPayLock;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private FieldMapper fieldMapper;

    @PostMapping("addAdv")
    @ApiOperation("客户往广告表中出入数据,生成订单")
    @ApiImplicitParam(value = "advertisement", name = "广告实体类", required = true, paramType = "body")
    public void addAdv(@RequestBody Advertisement advertisement, HttpServletRequest request) {

        advertisement.setAdvId(idWorker.nextId());

        String advToken = request.getHeader("advToken");

        Claims claims = jwtUtil.parseJwt(advToken);

        advertisement.setCustomer(claims.getId());

        advMapper.insert(advertisement);

    }

    @GetMapping("getField")
    @ApiOperation("查询所有广告栏位信息")
    public Result getField() {

        List<Field> fieldList = fieldMapper.selectAllField();

        return Result.response(ResultEnum.SUCCESS).setData(fieldList);
    }

    @GetMapping("getShowAdv")
    @ApiOperation("查询所有的已上架的广告信息")
    public Result getShowAdv() {

        Set<ZSetOperations.TypedTuple<String>> advShow = redisTemplate.boundZSetOps("advShow").range(0, -1);

        List<Advertisement> advertisements = new ArrayList<>();

        for (ZSetOperations.TypedTuple<String> stringTypedTuple : advShow) {

            Advertisement advertisement = JSONObject.parseObject(stringTypedTuple.getValue(), Advertisement.class);

            advertisements.add(advertisement);
        }

        return Result.response(ResultEnum.SUCCESS).setData(advertisements);

    }

    @PostMapping("getAdvPage/{advId}")
    @ApiOperation("根据广告id,计算每次用户点击时所产生的费用")
    @ApiImplicitParam(value = "advId", name = "广告id", required = true, paramType = "path")
    public Result getAdvPage(HttpServletRequest request, @PathVariable("advId") String advId) {

        String authToken = request.getHeader("authToken");

        Claims claims = jwtUtil.parseJwt(authToken);

        String key = "advPay";

        String payKey = "paykey";

        Long value = new Date().getTime() + 5000L;

        if (advPayLock.lock(payKey, String.valueOf(value))) {

            try {

                if (!redisTemplate.boundHashOps(key).hasKey(claims.getId())) {

                    redisTemplate.boundHashOps(key).put(claims.getId(), "ok");

                    Advertisement advertisement = advMapper.selectById(advId);

                    advertisement.setAdvPerclickMoney(BigDecimal.valueOf(1d));

                    advMapper.updateById(advertisement);

                    redisTemplate.boundHashOps(key).expire(15, TimeUnit.MINUTES);

                    return Result.response(ResultEnum.SUCCESS);
                }

                advPayLock.unlock(payKey, String.valueOf(value));

            }catch (Exception e) {

                e.printStackTrace();
            }

        }

        return Result.response(ResultEnum.ERROR);
    }

}
